''' 服务器、容器相关的处理程序 '''
from http.client import responses

from jinja2 import TemplateNotFound
import tornado
from tornado import web, gen
from tornado.httputil import url_concat
from tornado.options import options

import os
import shutil
import json
import logging
import time

from .base import BaseHandler
from utils.dbutil import MySQLConnection
from utils.pathutil import PathBuilder
from utils.jsonresult import JsonResult, json_result_encoder
from utils.dockerutil import DockerServerUtil
from utils.dockerutil import DockerServiceUtil

class ServersHandler(BaseHandler):
    @web.authenticated
    @gen.coroutine
    def get(self):
        user = self.get_current_user()
        nodes = DockerServerUtil.get_all_servers()
        self.render('servers.html', user=user, nodes=nodes)


class ImagesHandler(BaseHandler):
    @web.authenticated
    @gen.coroutine
    def get(self):
        user = self.get_current_user()
        self.render('images.html', user=user)

    @web.authenticated
    @gen.coroutine
    def post(self):
        request_data = json.loads(self.request.body.decode())
        operation = request_data.get('operation', '')
        operand = request_data.get('operand', '')

        json_result = JsonResult()

        call_func = dispatch_map.get(operation)
        if call_func is None:
            json_result.message = '无效的操作'
        else:
            call_func(operand, json_result)

        self.write(json.dumps(json_result, ensure_ascii=True, default=json_result_encoder))
        self.finish() 
    

    @staticmethod
    def get_images_from_db(operand, json_result):
        status = None
        if operand:
            status = operand.get('status', 0)
        
        sql = "select imageid, imagename, description, size, DATE_FORMAT(createdtime,'%Y-%m-%d %H:%i') as createdtime, status from image"
        if status is not None:
            sql += " where status=" + str(status)

        conn = MySQLConnection.get_connection()
        try:
            with conn.cursor() as cursor:
                cursor.execute(sql)
                json_result.data = cursor.fetchall()
        finally:
            conn.close()
    
    
    @staticmethod
    def update_image(operand, json_result):
        conn = MySQLConnection.get_connection()
        imageid = operand.get('imageid', 0)
        status = int(operand.get('status', '1'))
        description = operand.get('description', '')
        if not imageid:
            json_result.success = False
            json_result.message = "参数错误"
        else:
            try:
                with conn.cursor() as cursor:
                    sql = "update image set description='{}', status={} where imageid='{}'"
                    sql_formatted = sql.format(description, status, imageid)
                    cursor.execute(sql_formatted)
                    conn.commit()
            except Exception as ex:
                json_result.success = False
                json_result.message = "修改镜像描述失败"
                logging.error(ex)
            finally:
                conn.close()
    
    @staticmethod
    def new_image(operand, json_result):
        imagename = operand.get('imagename', '')
        size = float(operand.get('size', 0))
        created_time = time.strftime('%Y-%m-%d %H:%M',time.localtime(time.time()))
        description = operand.get('description', '')
        status = int(operand.get('status', '1'))

        if not imagename:
            json_result.success = False
            json_result.message = "参数错误"
        else:
            conn = MySQLConnection.get_connection()
            try:
                with conn.cursor() as cursor:
                    imageid = 0
                    cursor.callproc('image_new', args=(imagename, description, size, created_time, status, imageid))
                    conn.commit()
            except Exception as ex:
                json_result.success = False
                json_result.message = "添加镜像失败"
                logging.error(ex)
            finally:
                conn.close()
    

    @staticmethod
    def delete_image(operand, json_result):
        imageid = operand.get('imageid', 0)
        if not imageid:
            json_result.success = False
            json_result.message = "参数错误"
        else:
            conn = MySQLConnection.get_connection()
            try:
                with conn.cursor() as cursor:
                    sql = "select courseid from course where imageid={} limit 0,1".format(imageid)
                    cursor.execute(sql)
                    courseid = cursor.fetchone()
                    if courseid:
                        json_result.success = False
                        json_result.message = '该镜像关联课程，无法删除'
                    else:
                        sql = "delete from image where imageid={}".format(imageid)
                        cursor.execute(sql)
                        conn.commit()
            except Exception as ex:
                json_result.success = False
                json_result.message = "删除镜像失败"
                logging.error(ex)
            finally:
                conn.close()


class ServicesHandler(BaseHandler):
    @web.authenticated
    @gen.coroutine
    def get(self):
        user = self.get_current_user()
        services = DockerServiceUtil.get_all_services()
        self.render('services.html', user=user, services=services)
    
    # 删除容器服务
    @web.authenticated
    @gen.coroutine
    def post(self):
        service_name = self.get_argument('servicename')
        result = True
        try:
            DockerServiceUtil.remove_service(service_name)
        except:
            result = False
        
        self.write(json.dumps(result, ensure_ascii=True))    
        self.finish() 

dispatch_map = {
    'get_images_from_db' : ImagesHandler.get_images_from_db,
    'update_image' : ImagesHandler.update_image,
    'new_image' : ImagesHandler.new_image,
    'delete_image' : ImagesHandler.delete_image
}
    
default_handlers = [
    (r'/docker_servers', ServersHandler),
    (r'/docker_images', ImagesHandler),
    (r'/docker_services', ServicesHandler),    
]